﻿using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using SphinxClassLibrary;
using SphinxClassLibrary.Util;

namespace SphinxClassTests
{
    
    /// <summary>
    ///This is a test class for SphinxClientTest and is intended
    ///to contain all SphinxClientTest Unit Tests
    ///</summary>
    [TestClass()]
    public class SphinxClientTest
    {
        /// <summary>
        /// Change these settings accordingly
        /// </summary>
        private const string HOST = "localhost";
        private const int PORT = 9312;
        private const string INDEX = "idx_messages";
        private const string ATTRIBUTE = "author_id";
        private const SphinxClassLibrary.AttributeTypes ATTRIBUTE_TYPE = SphinxClassLibrary.AttributeTypes.SPH_ATTR_INTEGER;
        private const string QUERY = "test";
        private const string QUERY2 = "aba";

        private TestContext testContextInstance;


        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        /// <summary>
        ///A test for SphinxClient Constructor
        ///</summary>
        [TestMethod()]
        public void SphinxClientConstructorTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            Assert.IsNotNull(target);
        }

        /// <summary>
        ///A test for AddQuery
        ///</summary>
        [TestMethod()]
        public void AddQueryTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            string _comment = string.Empty;
            int actual = target.AddQuery(SphinxClientTest.QUERY, SphinxClientTest.INDEX, _comment);
            Assert.AreEqual(actual, 1);
        }

        /// <summary>
        /// A test for BuildExcerpts
        /// </summary>
        [TestMethod()]
        public void BuildExcerptsTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            List<string> _docs = new List<string>() { "one line goes here for testing", "another line" };
            string _words = "test";
            ExcerptOptions _opts = new ExcerptOptions();
            List<string> actual = target.BuildExcerpts(_docs, SphinxClientTest.INDEX, _words, _opts);
            Assert.IsTrue(actual.Count > 0, "Empty result set");
        }

        /// <summary>
        ///A test for BuildKeywords
        ///</summary>
        [TestMethod()]
        public void BuildKeywordsTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            bool _hits = true;
            List<Keyword> actual = target.BuildKeywords(SphinxClientTest.QUERY, SphinxClientTest.INDEX, _hits);
            Assert.IsTrue(actual.Count > 0, "Empty result set");
        }

        /// <summary>
        ///A test for FlushAttributes
        ///</summary>
        [TestMethod()]
        public void FlushAttributesTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            int actual = target.FlushAttributes();
            Assert.AreEqual(actual, 0);
        }

        /// <summary>
        ///A test for Query
        ///</summary>
        [TestMethod()]
        public void QueryTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            string _comment = string.Empty;
            Result actual = target.Query(SphinxClientTest.QUERY, SphinxClientTest.INDEX, _comment);
            Assert.IsTrue(actual.Status == SeachdStatusCodes.SEARCHD_OK, "Search failed: " + actual.Error);
        }

        /// <summary>
        ///A test for RunQueries
        ///</summary>
        [TestMethod()]
        public void RunQueriesTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            string _comment = string.Empty;
            Assert.AreEqual(1, target.AddQuery(SphinxClientTest.QUERY, SphinxClientTest.INDEX, _comment));
            Assert.AreEqual(2, target.AddQuery(SphinxClientTest.QUERY2, SphinxClientTest.INDEX, _comment));
            List<Result> actual = target.RunQueries();
            foreach (Result r in actual)
                Assert.IsTrue(r.Status == SeachdStatusCodes.SEARCHD_OK, "Search failed: " + r.Error);
            Assert.IsTrue(actual.Count > 0, "Empty result set");
        }

        /// <summary>
        ///A test for Status
        ///</summary>
        [TestMethod()]
        public void StatusTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            List<string> actual = target.Status();
            Assert.IsTrue(actual.Count > 0);
        }

        /// <summary>
        ///A test for UpdateAttributes
        ///</summary>
        [TestMethod()]
        public void UpdateAttributesTest()
        {
            SphinxClient target = new SphinxClient(SphinxClientTest.HOST, SphinxClientTest.PORT);
            List<SphinxClassLibrary.Attribute> _attrs = new List<SphinxClassLibrary.Attribute>();
            SphinxClassLibrary.Attribute _attribute = new SphinxClassLibrary.Attribute(SphinxClientTest.ATTRIBUTE, SphinxClientTest.ATTRIBUTE_TYPE);
            _attrs.Add(_attribute);
            Dictionary<long, List<SphinxClassLibrary.AttributeValue>> _values = new Dictionary<long, List<SphinxClassLibrary.AttributeValue>>();
            Result result_query = target.Query(SphinxClientTest.QUERY, SphinxClientTest.INDEX);
            foreach (SphinxClassLibrary.Match m in result_query.Matches)
            {
                _values[m.Id] = new List<SphinxClassLibrary.AttributeValue>();
                SphinxClassLibrary.AttributeValue _attrvalue = new SphinxClassLibrary.AttributeValue(_attribute);
                _attrvalue.AsInt = m.Attributes[SphinxClientTest.ATTRIBUTE].AsInt + 1;
                _values[m.Id].Add(_attrvalue);
                break;
            }
            int actual = target.UpdateAttributes(SphinxClientTest.INDEX, _attrs, _values);
            Assert.IsTrue(actual > 0, "No updates");
        }
    }
}
